home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / c / EasygadgetsSou.lha / EasyGadgets / HandleKeys.c < prev    next >
C/C++ Source or Header  |  1995-11-24  |  22KB  |  887 lines

  1. /*
  2.  *    File:                    HandleKeys.c
  3.  *    Description:    Handle vanilla shortcuts for gadgets
  4.  *
  5.  *    (C) 1995, Ketil Hunn
  6.  *
  7.  */
  8.  
  9. #ifndef EG_HANDLEKEYS_H
  10. #define EG_HANDLEKEYS_H
  11.  
  12. /*** PRIVATE INCLUDES ****************************************************************/
  13. #ifndef CLIB_INTUITION_PROTOS_H
  14. #include <clib/intuition_protos.h>
  15. #endif
  16.  
  17. #ifndef CLIB_GADTOOLS_PROTOS_H
  18. #include <clib/gadtools_protos.h>
  19. #endif
  20.  
  21. /*** DEFINES *************************************************************************/
  22. #define    every_node    node=list->lh_Head;node->ln_Succ;node=node->ln_Succ
  23.  
  24. #define SHIFTPRESSED(msg)    ((msg->Qualifier & IEQUALIFIER_LSHIFT) | (msg->Qualifier & IEQUALIFIER_RSHIFT))
  25. #define ALTPRESSED(msg)        ((msg->Qualifier & IEQUALIFIER_LALT) | (msg->Qualifier & IEQUALIFIER_RALT))
  26. #define CTRLPRESSED(msg)    (msg->Qualifier & IEQUALIFIER_CONTROL)
  27.  
  28. /*** PROTOTYPES **********************************************************************/
  29. __asm void egCloseAllTasks(register __a0 struct EasyGadgets    *eg);
  30.  
  31. /*** FUNCTIONS ***********************************************************************/
  32.  
  33. __asm ULONG egCallHook(    register __a0 void    *func,
  34.                                                 register __a1 APTR    msg)
  35. {
  36.     struct Hook    hook;
  37.     ULONG retvalue=1;
  38.  
  39. #ifdef MYDEBUG_H
  40.     DebugOut("egCallHook");
  41. #endif
  42.  
  43.     if(func)
  44.     {
  45.         hook.h_Entry        =(HOOKFUNC)func;
  46.         hook.h_SubEntry    =NULL;
  47.         hook.h_Data            =msg;
  48.  
  49.         retvalue=CallHookA(&hook, NULL, msg);
  50.     }
  51.     return retvalue;
  52. }
  53.  
  54. __asm __saveds UWORD egCountList(register __a0 struct List *list)
  55. {
  56.     register struct Node *node;
  57.     register UWORD count=0;
  58.  
  59.     if(!IsNil(list))
  60.         for(every_node)
  61.             ++count;
  62.  
  63.     return count;
  64. }
  65.  
  66. __asm __saveds LONG egHandleListviewArrows(register __a1 struct egGadget             *listview,
  67.                                                                                         register __a0 struct Window                *window,
  68.                                                                                         register __a2 struct IntuiMessage *msg)
  69. {
  70.     register WORD        scrollrows=(H(listview)/listview->ng.ng_TextAttr->ta_YSize)-1,
  71.                                     addon=1;
  72.     register BYTE        readonly=ISBITSET(listview->flags, EG_READONLY);
  73.     ULONG                        top;
  74.     struct TagItem    taglist[3];
  75.  
  76.     if(listview->active==~0)
  77.     {
  78.         listview->active=0L;
  79.         addon=0;
  80.     }
  81.  
  82.     SETTAG(taglist[0], GTLV_Top, (ULONG)&top);
  83.     SETTAG(taglist[1], TAG_DONE, TAG_DONE);
  84.     egGetGadgetAttrsA(listview, window, NULL, taglist);
  85.  
  86.     switch(msg->Code)
  87.     {
  88.         case CURSORUP:
  89.             if(CTRLPRESSED(msg) | ALTPRESSED(msg))
  90.                 listview->active=0L;
  91.             else if(SHIFTPRESSED(msg))
  92.             {
  93.                 if(readonly)
  94.                     listview->active=MIN(0, listview->active-scrollrows-1);
  95.                 else
  96.                 {
  97.                     if(listview->active>top)
  98.                         listview->active=(LONG)top;
  99.                     else
  100.                         listview->active=(LONG)MAX(0L, listview->active-scrollrows);
  101.                 }
  102.             }
  103.             else
  104.             {
  105.                 if(readonly)
  106.                     listview->active=MAX(0, listview->active-1);
  107.                 else
  108.                     listview->active=(LONG)MAX(0L, listview->active-addon);
  109.             }
  110.             break;
  111.         case CURSORDOWN:
  112.             if(CTRLPRESSED(msg) | ALTPRESSED(msg))
  113.                 listview->active=(LONG)listview->max;
  114.             else if(SHIFTPRESSED(msg))
  115.             {
  116.                 if(readonly)
  117.                     listview->active=MIN(listview->max, listview->active+scrollrows-1);
  118.                 else
  119.                 {
  120.                     if(listview->active!=top+scrollrows)
  121.                         listview->active=(LONG)MIN(listview->max, (UWORD)top+scrollrows);
  122.                     else
  123.                         listview->active=(LONG)MIN(listview->max, listview->active+scrollrows);
  124.                 }
  125.             }
  126.             else
  127.             {
  128.                 if(readonly)
  129.                     listview->active=MIN(listview->max, listview->active+scrollrows);
  130.                 else
  131.                     listview->active=(LONG)MIN(listview->max, listview->active+addon);
  132.             }
  133.             break;
  134.     }
  135.  
  136.     SETTAG(taglist[0], GTLV_Selected, listview->active);
  137.     SETTAG(taglist[1], (readonly ? GTLV_Top:GTLV_MakeVisible),    listview->active);
  138.     SETTAG(taglist[2], TAG_DONE, TAG_DONE);
  139.     egSetGadgetAttrsA(listview, window, NULL, taglist);
  140.  
  141.     return listview->active;
  142. }
  143.  
  144. __asm __saveds UBYTE egFindVanillaKey(register __a0 char *text)
  145. {
  146.     register UBYTE *c;
  147. #ifdef MYDEBUG_H
  148.     DebugOut("egFindVanillaKey");
  149. #endif
  150.  
  151.     if(c=StrChr(text, EG_Underscorechar))
  152.             return(ToUpper(*(c+1)));
  153.  
  154.     return 1;
  155. }
  156.  
  157. __asm struct egGadget *egMatchKey(register __a0 struct egGadget *gad,
  158.                                                                     register __d0 UBYTE                        key)
  159. {
  160.     register struct egGadget *found=NULL;
  161.  
  162. #ifdef MYDEBUG_H
  163.     DebugOut("egMatchKey");
  164. #endif
  165.  
  166.     if(key!=NULL)
  167.         while(gad!=NULL)
  168.         {
  169.             if(gad->key==key)
  170.             {
  171.                 found=gad;
  172.                 break;
  173.             }
  174.             gad=gad->NextGadget;
  175.         }
  176.     return found;
  177. }
  178.  
  179. __asm struct egGadget *egFindListview(register __a0 struct egGadget *gad)
  180. {
  181.     register struct egGadget *found=NULL;
  182.  
  183. #ifdef MYDEBUG_H
  184.     DebugOut("egFindListview");
  185. #endif
  186.  
  187.     while(gad!=NULL)
  188.     {
  189.         if(ISBITSET(gad->flags, EG_LISTVIEWARROWS))
  190.         {
  191.             found=gad;
  192.             break;
  193.         }
  194.         gad=gad->NextGadget;
  195.     }
  196.     return found;
  197. }
  198.  
  199. __asm struct egGadget *egFindGadget(register __a0 struct egGadget *gad,
  200.                                                                         register __d0 UWORD                        id)
  201. {
  202.     register struct egGadget *found=NULL;
  203.  
  204. #ifdef MYDEBUG_H
  205.     DebugOut("egFindGadget");
  206. #endif
  207.  
  208.     while(gad)
  209.     {
  210.         if(gad->ng.ng_GadgetID==id)
  211.         {
  212.             found=gad;
  213.             break;
  214.         }
  215.         gad=gad->NextGadget;
  216.     }
  217.     return found;
  218. }
  219.  
  220. __asm __saveds void egSetGadgetState(    register __a0 struct egGadget *gadget,
  221.                                                                             register __a1 struct Window     *window,
  222.                                                                             register __d0 BYTE                        state)
  223. {
  224. #ifdef MYDEBUG_H
  225.     DebugOut("egSetGadgetState");
  226. #endif
  227.  
  228.     if(gadget && window)
  229.         if(ISBITSET(gadget->flags, EG_DISABLED)==FALSE)
  230.         {
  231.             UWORD gadpos=RemoveGadget(window, gadget->gadget);
  232.             IFTRUESETBIT(state, gadget->gadget->Flags, GFLG_SELECTED);
  233.             AddGadget(window, gadget->gadget, gadpos);
  234.             RefreshGList(gadget->gadget, window, NULL, 1);
  235.         }
  236. }
  237.  
  238. __asm __saveds UBYTE egConvertRawKey(register __a0 struct IntuiMessage *msg)
  239. {
  240.     static struct InputEvent ev;
  241.     UBYTE buffer[9];
  242.     int len;
  243.  
  244. #ifdef MYDEBUG_H
  245.     DebugOut("egConvertRawKey");
  246. #endif
  247.  
  248.     if(msg->Class!=IDCMP_RAWKEY)
  249.         return 0;
  250.  
  251.     ev.ie_Class                  =IECLASS_RAWKEY;
  252.     ev.ie_Code               =msg->Code;
  253.     ev.ie_Qualifier     =msg->Qualifier;
  254.     ev.ie_EventAddress=*(APTR *)msg->IAddress;
  255.     len=MapRawKey(&ev, buffer, 8, NULL);
  256.     if(len!=1)
  257.         return 0;
  258.     return buffer[0];
  259. }
  260.  
  261. __asm void egHandleMultipleChoiceKind(register __a0 struct IntuiMessage *msg,
  262.                                                                             register __a1 struct egTask                *task,
  263.                                                                             register __d0 BYTE                                shift)
  264. {
  265.     if(shift)
  266.     {
  267.         if(task->activegad->active==0L)
  268.         {
  269.             if(task->activegad->kind==PALETTE_KIND)
  270.                 ;//msg->Code=1<<eg->RPort.BitMap->Depth;
  271.             else
  272.             {
  273.                 for(msg->Code=0; task->activegad->labels[msg->Code]!=NULL; msg->Code++)
  274.                     ;
  275.             }
  276.             --msg->Code;
  277.         }
  278.         else
  279.             msg->Code=task->activegad->active-1;
  280.     }
  281.     else
  282.     {
  283.         if(task->activegad->labels[task->activegad->active+1]==NULL)
  284.             msg->Code=0;
  285.         else
  286.             msg->Code=task->activegad->active+1;
  287.     }
  288.     task->activegad->active=(LONG)msg->Code;
  289.     GT_SetGadgetAttrs(task->activegad->gadget, task->window, task->req,
  290.                         GTCY_Active,    msg->Code,
  291.                         GTMX_Active,    msg->Code,
  292.                         TAG_DONE);
  293.     CLEARBIT(msg->Class, IDCMP_RAWKEY);
  294.     if(task->activegad->kind==MX_KIND)
  295.         SETBIT(msg->Class, IDCMP_GADGETDOWN);
  296.     else
  297.         SETBIT(msg->Class, IDCMP_GADGETUP);
  298.     msg->IAddress=task->activegad->gadget;
  299. }
  300.  
  301. __asm __saveds ULONG egWait(register __a0 struct EasyGadgets *eg,
  302.                                                         register __d0 ULONG                                signals)
  303. {
  304.      register ULONG signal=Wait(    signals                                                                                            |
  305.                                                             eg->AmigaGuideSignal                                                                |
  306.                                                             (eg->notifyport ? 1L<<eg->notifyport->mp_SigBit:0L) |
  307.                                                             1L<<eg->msgport->mp_SigBit);
  308.     if(signal & eg->AmigaGuideSignal)
  309.         egHandleAmigaGuide(eg);
  310.     if(signal & 1L<<eg->msgport->mp_SigBit)
  311.         egGetMsg(eg);
  312.  
  313.     if(eg->notifyport && (signal & 1L<<eg->notifyport->mp_SigBit))
  314.     {
  315.         register struct ScreenNotifyMessage *snm;
  316.     
  317.         while(snm=(struct ScreenNotifyMessage *)GetMsg(eg->notifyport))
  318.         {
  319.             register struct egTask    *task;
  320.  
  321.             eg->msg->Class        =EGIDCMP_NOTIFY;
  322.             eg->msg->Code            =(UWORD)snm->snm_Type;
  323.             eg->msg->IAddress    =snm->snm_Value;
  324.  
  325.             for(every_task)
  326.                 if(task->handlefunc)
  327.                     egCallHook(task->handlefunc, (APTR)eg);
  328.  
  329.             ReplyMsg((struct Message *) snm);
  330.         }
  331.     }
  332.  
  333.     return signal;
  334. }
  335.  
  336. __asm __saveds struct IntuiMessage *egGetMsg(register __a0 struct EasyGadgets    *eg)
  337. {
  338.     struct IntuiMessage *tmpmsg, *msg=NULL;
  339.     register struct egTask                *task;
  340.  
  341. #ifdef MYDEBUG_H
  342.     DebugOut("egGetMsg");
  343. #endif
  344.  
  345.     if(ISBITSET(eg->flags, EG_ICONIFIED))
  346.     {
  347.         register struct Message *msg;
  348.  
  349.         if(msg=GetMsg(eg->msgport))
  350.         {
  351.             ReplyMsg(msg);
  352.             egIconify(eg, FALSE);
  353.         }
  354.     }
  355.  
  356.     while(!IsNil(&eg->msgport->mp_MsgList))
  357.     {
  358.         switch(eg->msgport->mp_MsgList.lh_Head->ln_Type)
  359.         {
  360.             case NT_USER:
  361.                 break;
  362.             case EG_INTUIMSG:
  363.                 if(msg=(struct IntuiMessage *)GetMsg(eg->msgport))
  364.                 {
  365.                     CopyMem(msg, eg->msg, sizeof(struct IntuiMessage));
  366.                     for(task=eg->tasklist; task; task=task->nexttask)
  367.                     {
  368.                         if(task->status==STATUS_OPEN && task->window==msg->IDCMPWindow && task->handlefunc)
  369.                             egCallHook(task->handlefunc, (APTR)eg);
  370.                         break;
  371.                     }
  372.                     FreeVec(msg);
  373.                 }
  374.                 break;
  375.             default:
  376.                 if(tmpmsg=GT_GetIMsg(eg->msgport))
  377.                 {
  378.                     CopyMem(tmpmsg, eg->msg, sizeof(struct IntuiMessage));
  379.                     GT_ReplyIMsg(tmpmsg);
  380.                     msg=eg->msg;
  381.  
  382.         for(task=eg->tasklist; task; task=task->nexttask)
  383.             if(task->status==STATUS_OPEN && task->window==msg->IDCMPWindow)
  384.             {
  385.                 switch(msg->Class)
  386.                 {
  387.                     case IDCMP_REFRESHWINDOW:
  388.                         GT_BeginRefresh(task->window);
  389.                         if(task->refreshfunc)
  390.                             egCallHook(task->refreshfunc, (APTR)msg);
  391.                         GT_EndRefresh(task->window, TRUE);
  392.                         break;
  393.                     case IDCMP_SIZEVERIFY:
  394.                         egFreeGList(task);
  395.                         RefreshWindowFrame(task->window);
  396.                         break;
  397.                     case IDCMP_NEWSIZE:
  398.                         if(task->renderfunc)
  399.                         {
  400.                             if(task->glist)
  401.                             {
  402.                                 egFreeGList(task);
  403.                                 RefreshWindowFrame(task->window);
  404.                             }
  405.                             eg->dri=task->dri;
  406.                             egCallHook(task->renderfunc, (APTR)msg);
  407.                             egRenderGadgets(task);
  408.                         }
  409.                         if(task->refreshfunc)
  410.                             egCallHook(task->refreshfunc, (APTR)msg);
  411.                         break;
  412. /*                    case IDCMP_CLOSEWINDOW:
  413.                         if(task==task->eg->tasklist)
  414.                             egCloseAllTasks(task->eg);
  415.                         else
  416.                             egCloseTask(task);
  417.                         break;
  418. */
  419.                     case IDCMP_MENUHELP:
  420.                         {
  421.                             UBYTE title[MAXCHARS];
  422.                             register struct Menu *menu=task->window->MenuStrip;
  423.                             register ULONG count=MENUNUM(msg->Code);
  424.  
  425.                             for(; menu && count-->0; menu=menu->NextMenu)
  426.                                 ;
  427.                             if(menu)
  428.                             {
  429.                                 sprintf(title, "Menu_%ld", MENUNUM(msg->Code)+1);
  430.                                 egShowAmigaGuide(eg, title);
  431.                             }
  432.                         }
  433.                         break;
  434.                     case IDCMP_VANILLAKEY:
  435.                     case IDCMP_RAWKEY:
  436.                         if(msg->Code==CURSORUP | msg->Code==CURSORDOWN)
  437.                         {
  438.                             struct egGadget *listview;
  439.  
  440.                             if(listview=egFindListview(task->eglist))
  441.                             {
  442.                                 register UWORD oldactive=(UWORD)listview->active;
  443.  
  444.                                 if(oldactive!=(msg->Code=(UWORD)egHandleListviewArrows(listview, task->window, msg)))
  445.                                 {
  446.                                     CLEARBIT(msg->Class, IDCMP_RAWKEY);
  447.                                     SETBIT(msg->Class, IDCMP_GADGETUP);
  448.                                     msg->IAddress=listview->gadget;
  449.                                 }
  450.                             }
  451.                         }
  452.                         else if(msg->Code!=95)
  453.                         {
  454.                             int upstroke=msg->Code & 0x80;
  455.                             BYTE shift=(BYTE)((msg->Qualifier & IEQUALIFIER_LSHIFT) | (msg->Qualifier & IEQUALIFIER_RSHIFT));
  456.  
  457.                             if(task->activegad)    // key released
  458.                             {
  459.                                 int samekey=(msg->Code & 0x7f)==task->activekey;
  460.  
  461.                                 if(samekey && !upstroke)
  462.                                     break;
  463.  
  464.                                 egSetGadgetState(task->activegad, task->window, FALSE);
  465.  
  466.                                 if(samekey)
  467.                                 {
  468.                                     switch(task->activegad->kind)
  469.                                     {
  470.                                         case CYCLE_KIND:
  471.                                             egHandleMultipleChoiceKind(msg, task, shift);
  472.                                             break;
  473.                                         case BUTTON_KIND:
  474.                                         case EG_GETFILE_KIND:
  475.                                         case EG_GETDIR_KIND:
  476.                                         case EG_POPUP_KIND:
  477.                                             CLEARBIT(msg->Class, IDCMP_RAWKEY);
  478.                                             SETBIT(msg->Class, IDCMP_GADGETUP);
  479.                                             msg->IAddress=task->activegad->gadget;
  480.                                             break;
  481.                                     }
  482.                                 }
  483.                                 task->activegad=NULL;
  484.                                 task->activekey=0;
  485.                             }
  486.                             else // new key pressed
  487.                             {
  488.                                 UBYTE keypress=egConvertRawKey(msg);
  489.                                 struct egGadget *eggad=egMatchKey(task->eglist, ToUpper(keypress));
  490.  
  491.                                 if(eggad==NULL)
  492.                                     break;
  493.                                 if(ISBITSET(eggad->flags, EG_DISABLED))
  494.                                     break;
  495.  
  496.                                 switch(eggad->kind)
  497.                                 {
  498.                                     case BUTTON_KIND:
  499.                                     case EG_GETFILE_KIND:
  500.                                     case EG_GETDIR_KIND:
  501.                                     case EG_POPUP_KIND:
  502.                                     case CYCLE_KIND:
  503.                                         task->activegad=eggad;
  504.                                         task->activekey=msg->Code;
  505.                                         egSetGadgetState(eggad, task->window, TRUE);
  506.                                         msg=NULL;
  507.                                         break;
  508.                                     case STRING_KIND:
  509.                                     case INTEGER_KIND:
  510.                                         egActivateGadget(eggad, task->window, task->req);
  511.                                         break;
  512.                                     case SLIDER_KIND:
  513.                                     case SCROLLER_KIND:
  514.                                     case LISTVIEW_KIND:
  515.                                         {
  516.                                             register BYTE addon=1;
  517.                                             register LONG oldactive=eggad->active;
  518.  
  519.                                             if(eggad->kind==LISTVIEW_KIND)
  520.                                             {
  521.                                                 if(eggad->active==EG_LISTVIEW_NONE)
  522.                                                 {
  523.                                                     eggad->active=0L;
  524.                                                     addon=0;
  525.                                                 }
  526.                                             }
  527.  
  528.                                              if(shift)
  529.                                                 eggad->active=(LONG)MAX(eggad->active-addon, eggad->min);
  530.                                             else
  531.                                                 eggad->active=(LONG)MIN(eggad->active+addon, eggad->max);
  532.  
  533.                                             {
  534.                                                 struct TagItem taglist[6];
  535.  
  536.                                                 SETTAG(taglist[0], GTSL_Level,                msg->Code=(UWORD)eggad->active);
  537.                                                 SETTAG(taglist[1], GTSC_Top,                    msg->Code);
  538.                                                 SETTAG(taglist[2], GTPA_Color,                msg->Code);
  539.                                                 SETTAG(taglist[3], GTLV_Selected,            msg->Code);
  540.                                                 SETTAG(taglist[4], GTLV_MakeVisible,    msg->Code);
  541.                                                 SETTAG(taglist[5], TAG_DONE, TAG_DONE);
  542.  
  543.                                                 egSetGadgetAttrsA(msg->IAddress=eggad->gadget,
  544.                                                                                     task->window,
  545.                                                                                     task->req,
  546.                                                                                     taglist);
  547. /*
  548.                                             GT_SetGadgetAttrs(msg->IAddress=eggad->gadget, task->window, task->req,
  549.                                                                                 GTSL_Level,                msg->Code=(UWORD)eggad->active,
  550.                                                                                 GTSC_Top,                    msg->Code,
  551.                                                                                 GTPA_Color,                msg->Code,
  552.                                                                                 GTLV_Selected,        msg->Code,
  553. //                                                                                (KickStart<39 ? GTLV_Top : GTLV_MakeVisible), msg->Code,
  554.                                                                                 GTLV_MakeVisible, msg->Code,
  555.                                                                                 TAG_DONE);
  556. */
  557.                                             }
  558.                                             CLEARBIT(msg->Class, IDCMP_RAWKEY);
  559.                                             if(eggad->kind==LISTVIEW_KIND)
  560.                                             {
  561.                                                 if(oldactive!=eggad->active)
  562.                                                     SETBIT(msg->Class, IDCMP_GADGETUP);
  563.                                             }
  564.                                             else
  565.                                                 SETBIT(msg->Class, IDCMP_MOUSEMOVE);
  566.                                         }
  567.                                         break;
  568.                                     case CHECKBOX_KIND:
  569.                                         eggad->active=!eggad->active;
  570.                                         GT_SetGadgetAttrs(msg->IAddress=eggad->gadget, task->window, task->req,
  571.                                                             GTCB_Checked,    msg->Code=(UWORD)eggad->active,
  572.                                                             TAG_DONE);
  573.                                         CLEARBIT(msg->Class, IDCMP_RAWKEY);
  574.                                         SETBIT(msg->Class, IDCMP_GADGETUP);
  575.                                         break;
  576.                                     case PALETTE_KIND:
  577.                                     case MX_KIND:
  578.                                         task->activegad=eggad;
  579.                                         egHandleMultipleChoiceKind(msg, task, shift);
  580.                                         break;
  581.                                 }
  582.                             }
  583.                         }
  584.                         else
  585.                             egShowAmigaGuide(eg, egGetHelpNode(task, msg));
  586.                         break;
  587.                     
  588.                     case IDCMP_CHANGEWINDOW:
  589.                         task->coords.LeftEdge    =task->window->LeftEdge;
  590.                         task->coords.TopEdge    =task->window->TopEdge;
  591.                         task->coords.Width        =task->window->Width;
  592.                         task->coords.Height        =task->window->Height;
  593.                         break;
  594.                     case IDCMP_MENUVERIFY:
  595.                     case IDCMP_INACTIVEWINDOW:
  596.                         if(task->activegad)
  597.                         {
  598.                             egSetGadgetState(task->activegad, task->window, FALSE);
  599.                             task->activegad=NULL;
  600.                             task->activekey=0;
  601.                         }
  602.                         break;
  603.                     case IDCMP_GADGETDOWN:
  604.                         if(msg->IAddress)
  605.                         {
  606.                             register struct egGadget *gad=egFindGadget(task->eglist, ((struct Gadget *)msg->IAddress)->GadgetID);
  607.  
  608.                             switch(gad->kind)
  609.                             {
  610.                                 case PALETTE_KIND:
  611.                                 case MX_KIND:
  612.                                     gad->active=(LONG)msg->Code;
  613.                                     break;
  614.                             }
  615.                         }
  616.                         break;
  617.                     case IDCMP_GADGETUP:
  618.                         if(msg->IAddress)
  619.                         {
  620.                             register struct egGadget *gad=egFindGadget(task->eglist, ((struct Gadget *)msg->IAddress)->GadgetID);
  621.  
  622.                             if(msg->IAddress==task->iconifygadget)
  623.                                 egIconify(task->eg, TRUE);
  624.                             else
  625.                             {
  626.                                 if(msg->Code==95) // help inside string
  627.                                     egShowAmigaGuide(eg, egGetHelpNode(task, msg));
  628.                                 if(gad)
  629.                                     switch(gad->kind)
  630.                                     {
  631.                                         case CYCLE_KIND:
  632.                                         case LISTVIEW_KIND:
  633.                                         case CHECKBOX_KIND:
  634.                                             gad->active=(LONG)msg->Code;
  635.                                             break;
  636.                                         case SLIDER_KIND:
  637.                                         case SCROLLER_KIND:
  638.                                             gad->active=(LONG)msg->Code;
  639.                                             break;
  640.                                     }
  641.                             }
  642.                         }
  643.                         break;
  644.                     case IDCMP_MOUSEMOVE:
  645.                         if(msg->IAddress)
  646.                         {
  647.                             register struct egGadget *gad=egFindGadget(task->eglist, ((struct Gadget *)msg->IAddress)->GadgetID);
  648.  
  649.                             if(gad)
  650.                                 switch(gad->kind)
  651.                                 {
  652.                                     case SLIDER_KIND:
  653.                                     case SCROLLER_KIND:
  654.                                         gad->active=(LONG)msg->Code;
  655.                                         break;
  656.                                 }
  657.                         }
  658.                 }
  659.                 if(msg && task->handlefunc)
  660.                     egCallHook(task->handlefunc, (APTR)msg);
  661.                 break;
  662.             }
  663.             }
  664.             break;
  665.         }
  666.     }
  667.     return msg;
  668. }
  669.  
  670. __asm __saveds LONG egSetGadgetAttrsA(register __a0 struct egGadget     *newgad,
  671.                                                                             register __a1 struct Window            *win,
  672.                                                                             register __a2 struct Requester    *req,
  673.                                                                             register __a3 struct TagItem        *taglist)
  674. {
  675.     struct TagItem                    *tstate=taglist;
  676.     register struct TagItem    *tag;
  677.     register BYTE                        mark=FALSE, makevisible=FALSE;
  678.     ULONG                                        newtop=0;
  679.  
  680. #ifdef MYDEBUG_H
  681.     DebugOut("egSetGadgetAttrsA");
  682. #endif
  683.  
  684.     if(win==NULL)
  685.         return 0L;
  686.     while(tag=NextTagItem(&tstate))
  687.         switch(tag->ti_Tag)
  688.         {
  689.             case GTCY_Labels:
  690.             case GTMX_Labels:
  691.                 newgad->labels=(STRPTR *)tag->ti_Data;
  692.                 break;
  693.             case GTLV_Labels:
  694.                 if(tag->ti_Data==~0)
  695.                 {
  696.                     newgad->list=NULL;
  697.                     newgad->max=0L;
  698.                 }
  699.                 else
  700.                 {
  701.                     newgad->list=(struct List *)tag->ti_Data;
  702.                     newgad->max=MAX(0, (egCountList(newgad->list)-1));
  703.                 }
  704.                 break;
  705.             case GTLV_Top:
  706.                 newgad->min=(WORD)tag->ti_Data;
  707.                 break;
  708.             case GTCY_Active:
  709.             case GTMX_Active:
  710.             case GTCB_Checked:
  711.             case GTPA_Color:
  712.             case GTLV_Selected:
  713.             case GTSL_Level:
  714.                 newgad->active=(LONG)tag->ti_Data;
  715.                 break;
  716.             case GTLV_SelectedNode:
  717.                 {
  718.                     register struct Node *node, *marknode=(struct Node *)tag->ti_Data;
  719.                     register LONG select=0;
  720.  
  721.                     if(!IsNil(newgad->list))
  722.                         for(node=newgad->list->lh_Head;node->ln_Succ;node=node->ln_Succ)
  723.                             if(marknode==node)
  724.                             {
  725.                                 newgad->active=select;
  726.                                 mark=TRUE;
  727.                                 tag->ti_Tag=TAG_IGNORE;
  728. //                                tag->ti_Data=select;
  729.                                 break;
  730.                             }
  731.                             else
  732.                                 ++select;
  733.                 }
  734.                 break;
  735.             case GTSL_Min:
  736.                 newgad->min=(WORD)tag->ti_Data;
  737.                 break;
  738.             case GTSL_Max:
  739.                 newgad->max=(WORD)tag->ti_Data;
  740.                 break;
  741.             case GTPA_Depth:
  742.                 newgad->max=(WORD)1<<tag->ti_Data;
  743.                 break;
  744.             case GA_Disabled:
  745.                 if(tag->ti_Data)
  746.                     if(ISBITSET(newgad->flags, EG_DISABLED))
  747.                         tag->ti_Tag=TAG_IGNORE;
  748.  
  749.                 IFTRUESETBIT(tag->ti_Data, newgad->flags, EG_DISABLED);
  750.  
  751.                 if(newgad->kind>=EG_GETFILE_KIND)
  752.                     if(ISBITSET(newgad->flags, EG_DISABLED))
  753.                         OffGadget(newgad->gadget, win, req);
  754.                     else
  755.                         OnGadget(newgad->gadget, win, req);
  756.                 break;
  757.             case GTLV_MakeVisible:
  758.                 if(KickStart<39)
  759.                 {
  760.                     struct TagItem    taglist[2];
  761.                     ULONG                        top;
  762.  
  763.                     SETTAG(taglist[0], GTLV_Top, (ULONG)&top);
  764.                     SETTAG(taglist[1], TAG_DONE, TAG_DONE);
  765.                     egGetGadgetAttrsA(newgad, win, req, taglist);
  766.  
  767.                     if(tag->ti_Data<top)
  768.                         newtop=tag->ti_Data;
  769.                     else
  770.                     {
  771.                         register ULONG scrollrows=(H(newgad)/newgad->ng.ng_TextAttr->ta_YSize)-1;
  772.  
  773.                         newtop=top;
  774.                         if(top+scrollrows<tag->ti_Data)
  775.                             newtop=MAX(0, tag->ti_Data-scrollrows);
  776.                     }
  777.                     mark=makevisible=TRUE;
  778.                 }
  779.                 break;
  780.         }
  781.  
  782.     if(mark)
  783.         GT_SetGadgetAttrs(newgad->gadget, win, req,
  784.                                         GTLV_Selected,                                                newgad->active,
  785.                                         (makevisible ? GTLV_Top:TAG_IGNORE),    newtop,
  786.                                         TAG_MORE, taglist,
  787.                                         TAG_END);
  788.     else
  789.         GT_SetGadgetAttrsA(newgad->gadget, win, req, taglist);
  790.  
  791.     return newgad->active;
  792. }
  793.  
  794. __asm __saveds struct Node *egGetNode(register __a0 struct List *list,
  795.                                                                             register __d0 ULONG                selected)
  796. {
  797.     register struct Node *node;
  798.     register UWORD i=0;
  799.  
  800. #ifdef MYDEBUG_H
  801.     DebugOut("egGetSelectedNode");
  802. #endif
  803.  
  804.     if(!IsNil(list))
  805.         for(every_node)
  806.             if(i==selected)
  807.                 return node;
  808.             else
  809.                 ++i;
  810.  
  811.     return NULL;
  812. }
  813.  
  814. __asm __saveds void egGetGadgetAttrsA(register __a0 struct egGadget     *newgad,
  815.                                                                             register __a1 struct Window            *win,
  816.                                                                             register __a2 struct Requester    *req,
  817.                                                                             register __a3 struct TagItem        *taglist)
  818. {
  819.         struct TagItem    *tstate=taglist;
  820.         register struct TagItem    *tag;
  821.         ULONG                        *p;
  822.  
  823. #ifdef MYDEBUG_H
  824.     DebugOut("egGetGadgetAttrsA");
  825. #endif
  826.  
  827.     if(KickStart>38)
  828.         GT_GetGadgetAttrsA(newgad->gadget, win, req, taglist);
  829.     else
  830.     {
  831.         while(tag=NextTagItem(&tstate))
  832.         {
  833.             p=(ULONG *)tag->ti_Data;
  834.  
  835.             switch(tag->ti_Tag)
  836.             {
  837.                 case GA_Disabled:
  838.                     *p=(ULONG)ISBITSET(newgad->flags, EG_DISABLED);
  839.                     break;
  840.                 case GTCB_Checked:
  841.                 case GTCY_Active:
  842.                 case GTMX_Active:
  843.                 case GTPA_Color:
  844.                 case GTLV_Selected:
  845.                     *p=(ULONG)newgad->active;
  846.                     break;
  847.                 case GTCY_Labels:
  848.                     *p=(ULONG)newgad->labels;
  849.                     break;
  850.                 case GTIN_Number:
  851.                     *p=(ULONG)Number(newgad);
  852.                     break;
  853.                 case GTLV_Labels:
  854.                     *p=(ULONG)newgad->list;
  855.                     break;
  856.                 case GTLV_Top:
  857.                     *p=(ULONG)*(short *)(((char *)newgad->gadget)+sizeof(struct Gadget)+4);
  858.                     break;
  859.                 case GTSC_Top:
  860.                 case GTSL_Level:
  861.                     *p=(ULONG)newgad->active;
  862.                     break;
  863.                 case GTSC_Total:
  864.                     break;
  865.                 case GTSC_Visible:
  866.                     break;
  867.                 case GTSL_Min:
  868.                     *p=(ULONG)newgad->min;
  869.                     break;
  870.                 case GTSL_Max:
  871.                     *p=(ULONG)newgad->max;
  872.                     break;
  873.                 case GTST_String:
  874.                     *p=(ULONG)String(newgad);
  875.                     break;
  876.             }
  877.         }
  878.     }
  879.     if(tag=FindTagItem(GTLV_SelectedNode, taglist))
  880.     {
  881.         p=(ULONG *)tag->ti_Data;
  882.         *p=(ULONG)egGetNode(newgad->list, newgad->active);
  883.     }
  884. }
  885.  
  886. #endif
  887.